package org.jeecg.modules.paycenter.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.paycenter.channel.constant.CommonConstants;
import org.jeecg.modules.wlhy.utils.R;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.PayConstants;
import org.jeecg.modules.annotation.RequestLog;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jeecg.modules.paycenter.dto.PayDto;
import org.jeecg.modules.paycenter.service.PayService;
import org.jeecg.modules.paycenter.service.ZhengZhouPayService;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.wlhy.hyplatform.entity.HyPlatformCost;
import org.jeecg.modules.wlhy.shipping.entity.HyShippingNote;
import org.jeecg.modules.wlhy.shipping.service.IHyShippingNoteService;
import org.jeecg.modules.wlhy.utils.R;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * @author yangqf
 * @date 2023/6/24 17:03
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/pay/zhengzhou")
public class HyZhengZhouBankPayController {

    @Value("${pay-config.trade.begin:8}")
    private String TRADE_BEGIN;

    @Value("${pay-config.trade.end:19}")
    private String TRADE_END;

    @Resource
    private ISysUserService userService;
    @Resource
    private ZhengZhouPayService payService;
    @Resource
    private BaseCommonService baseCommonService;
    @Resource
    private IHyShippingNoteService shippingNoteService;
    @PostMapping("hyShippingNote/pay")
    @RequestLog(description = "重构版支付接口")
    public R shippingPay(@RequestBody @Validated PayDto payDto, HttpServletRequest req) {
        if (DateUtil.hour(new Date(), true)>Integer.parseInt(TRADE_END) || DateUtil.hour(new Date(), true) < Integer.parseInt(TRADE_BEGIN)){
            return R.failed("不在交易时间内, 详情请咨询系统管理员！");
        }

        //1、验证用户是否存在
        SysUser loginUser  = userService.getById(payDto.getUid());
        if (ObjectUtil.isEmpty(loginUser)) {
            return R.failed("用户不存在");
        }

        baseCommonService.addLog("单笔支付: 运单ID为：" + payDto.getId()+"用户名："+loginUser.getUsername() , CommonConstant.LOG_TYPE_2, CommonConstant.LOG_TYPE_2);

        //2、验证运单是否存在
        HyShippingNote hyShippingNote = shippingNoteService.getById(payDto.getId());
        if (!PayConstants.SHIPPING_PAY_STATUS.COMPLETE_APPROVAL.equals(hyShippingNote.getShippingPayStatus())) {
            return R.failed("未审核通过,不能支付!");
        }
        //3、进一步验证支付前的相关运单信息
        R checkResult = payService.checkOrderInfo(hyShippingNote, payDto, req);
        //验证信息异常则直接返回
        if (CommonConstants.FAIL == checkResult.getCode()) {
            return checkResult;
        }
        R accountCheckResult = payService.checkAccountInfo(hyShippingNote, false);
        //4、验证信息异常则直接返回
        if (CommonConstants.FAIL == accountCheckResult.getCode()) {
            return accountCheckResult;
        }
        //5、开始进行支付（既把支付状态改为支付中）
        boolean saveResult = payService.modifyShippingNotePayInfo(hyShippingNote, loginUser);
        if (!saveResult) {
            return R.failed("待支付->支付中失败");
        }
        //6、创建各种流水单
        payService.createStatement(hyShippingNote);
        //7、开始真正支付逻辑
        //如果支付失败则标记一下
        R payResult = payService.payActivity(hyShippingNote);
        if (CommonConstants.FAIL == checkResult.getCode()) {
            hyShippingNote.setShippingPayStatus("7");
            shippingNoteService.updateById(hyShippingNote);
            payService.updateHyBillForFail(hyShippingNote);
        } else { //更新一下Hy_bill这个表
            payService.updateHyBill(hyShippingNote);
        }
        return payResult;
    }


    @PostMapping("hyShippingNote/repay")
    @RequestLog(description = "重构版重新支付接口")
    public R shippingRePay(@RequestBody @Validated PayDto payDto, HttpServletRequest req) {
        if (DateUtil.hour(new Date(), true)>Integer.parseInt(TRADE_END) || DateUtil.hour(new Date(), true) < Integer.parseInt(TRADE_BEGIN)){
            return R.failed("不在交易时间内, 详情请咨询系统管理员！");
        }
        //1、验证用户是否存在
        SysUser loginUser  = userService.getById(payDto.getUid());
        if (ObjectUtil.isEmpty(loginUser)) {
            return R.failed("用户不存在");
        }

        baseCommonService.addLog("重新支付: 运单ID为：" + payDto.getId()+"用户名："+loginUser.getUsername() , CommonConstant.LOG_TYPE_2, CommonConstant.LOG_TYPE_2);

        //2、验证运单是否存在
        HyShippingNote hyShippingNote = shippingNoteService.getById(payDto.getId());
        if (ObjectUtil.isEmpty(hyShippingNote)) {
            return R.failed("运单不存在");
        }

        if (!PayConstants.SHIPPING_PAY_STATUS.FAIL_PAY.equals(hyShippingNote.getShippingPayStatus())) {
            return R.failed("订单状态不是支付失败的订单，不能重新发起支付");
        }
        //3、进一步验证支付前的相关运单信息
        R checkResult = payService.checkOrderInfo(hyShippingNote, payDto, req);
        //验证信息异常则直接返回
        if (CommonConstants.FAIL == checkResult.getCode()) {
            return checkResult;
        }
        R accountCheckResult = null;
        if (2 == payDto.getOperateType()) { //平台代付校验
            accountCheckResult = payService.checkPlateAccountInfoPaySingle(hyShippingNote, payDto,true);
        } else {
            accountCheckResult = payService.checkAccountInfo(hyShippingNote, true);
        }
        //4、验证信息异常则直接返回
        if (CommonConstants.FAIL == checkResult.getCode()) {
            return accountCheckResult;
        }
        //5、开始进行支付（既把支付状态改为支付中）
        boolean saveResult = payService.modifyShippingNoteRePayInfo(hyShippingNote, loginUser);
        if (!saveResult) {
            return R.failed("待支付->支付中失败");
        }

        //6、开始真正支付逻辑(再次支付不需要创建流水单了，因为之前创建过了)
        //如果支付失败则标记一下
        R payResult = null;
        if (2 == payDto.getOperateType()) { //平台代付校验
            payResult = payService.platePayActivity(hyShippingNote);
        } else {
            payResult = payService.payActivity(hyShippingNote);
        }
        if (CommonConstants.FAIL == checkResult.getCode()) {
            hyShippingNote.setShippingPayStatus("7");
            shippingNoteService.updateById(hyShippingNote);
            payService.updateHyBillForFail(hyShippingNote);
        } else { //更新一下Hy_bill这个表
            payService.updateHyBill(hyShippingNote);
        }
        return payResult;

    }

    /**
     * 平台单笔代付
     *
     * @param payDto
     * @return
     */
    @PostMapping("hyShippingNote/platePay")
    @RequestLog(description = "平台单笔代付")
    public R platePay(@RequestBody @Validated PayDto payDto,HttpServletRequest req) {

        if (DateUtil.hour(new Date(), true)>Integer.parseInt(TRADE_END) || DateUtil.hour(new Date(), true) < Integer.parseInt(TRADE_BEGIN)){
            return R.failed("不在交易时间内, 详情请咨询系统管理员！");
        }

        //1、验证用户是否存在
        SysUser loginUser  = userService.getById(payDto.getUid());
        if (ObjectUtil.isEmpty(loginUser)) {
            return R.failed("用户不存在");
        }

        baseCommonService.addLog("平台单笔代付: 运单ID号为：" + payDto.getId()+"用户名："+loginUser.getUsername() , CommonConstant.LOG_TYPE_2, CommonConstant.LOG_TYPE_2);

        //2、验证运单信息
        HyShippingNote hyShippingNote = shippingNoteService.getById(payDto.getId());
        if (ObjectUtil.isEmpty(hyShippingNote)) {
            return R.failed("请选择正确的运单！");
        }

        if (!PayConstants.SHIPPING_PAY_STATUS.COMPLETE_APPROVAL.equals(hyShippingNote.getShippingPayStatus())) {
            return R.failed("未审核通过,不能支付!");
        }

        payDto.setOperateType(2);
        //3、进一步验证支付前的相关运单信息
        R checkResult = payService.checkOrderInfo(hyShippingNote, payDto, req);
        if (CommonConstants.FAIL == checkResult.getCode()) {
            return checkResult;
        }
        //4、检查账户信息
        R accountCheckResult = payService.checkPlateAccountInfoPaySingle(hyShippingNote, payDto, false);
        if (CommonConstants.FAIL == checkResult.getCode()) {
            return accountCheckResult;
        }
        //5、创建
        HyPlatformCost platformCost = payService.createPlateStatement(hyShippingNote, loginUser);
        if (ObjectUtil.isNull(platformCost)) {
            return R.failed("创建平台流水单失败");
        }

        //5、开始进行支付（既把支付状态改为支付中）
        boolean saveResult = payService.modifyShippingNoteForPlatePay(hyShippingNote, loginUser, platformCost.getId());
        if (!saveResult) {
            log.error(hyShippingNote.getShippingNoteNumber(), "待支付->支付中失败");
        }
        //6、开始创建各种流水单
        boolean result = payService.createStatementForPlatePay(hyShippingNote);
        if (result) {
            R payResult = payService.platePayActivity(hyShippingNote);
            //如果支付失败则标记一下
            if (CommonConstants.FAIL == checkResult.getCode()) {
                hyShippingNote.setShippingPayStatus("7");
                shippingNoteService.updateById(hyShippingNote);
                payService.updateHyBillForFail(hyShippingNote);
            } else { //更新一下Hy_bill这个表
                payService.updateHyBillForPlatePay(hyShippingNote, platformCost);
            }

        } else {
            log.error("{}创建流水单失败", hyShippingNote.getShippingNoteNumber());
        }
        return R.failed(hyShippingNote.getShippingNoteNumber(),"支付成功");
    }

}
